// ml:run = $bin < input
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

using ll = long long;

struct edge { int to; ll cost; };

int const maxn = 100007;
ll back[maxn], f2[maxn];
ll down[maxn];
ll down2[maxn];
ll ans[maxn];
int choose[maxn];
int choose2[maxn];
ll value[maxn];
int n;

std::vector<std::vector<edge>> tree;

void init()
{
    tree.clear(); tree.resize(n + 1);
    std::fill(back, back + n + 1, 0);
    std::fill(f2, f2 + n + 1, 0);
    std::fill(down, down + n + 1, 0);
    std::fill(choose, choose + n + 1, 0);
    std::fill(choose2, choose2 + n + 1, 0);
    std::fill(ans, ans + n + 1, 0);
}

void add_edge(int u, int v, ll cost)
{
    tree[u].push_back({v, cost});
    tree[v].push_back({u, cost});
}

void dfs(int u, int father = -1)
{
    back[u] = down[u] = value[u];
    for (auto i : tree[u]) {
        auto v = i.to;
        auto c = i.cost;
        if (v == father) continue;
        dfs(v, u);
        if (back[v] - 2 * c > 0) back[u] += back[v] - 2 * c;
    }
    ll max = value[u];
    for (auto i : tree[u]) {
        auto v = i.to;
        auto c = i.cost;
        if (v == father) continue;
        auto tmp = back[u];
        if (back[v] - 2 * c > 0) tmp -= back[v] - 2 * c;
        if (down[v] + tmp - c  > max) {
            max = down[v] + tmp - c;
            choose[u] = v;
        }
    }
    down[u] = max;
    max = 0;
    for (auto i : tree[u]) {
        auto v = i.to;
        auto c = i.cost;
        if (v == father || v == choose[u]) continue;
        auto tmp = back[u];
        if (back[v] - 2 * c > 0) tmp -= back[v] - 2 * c;
        if (down[v] + tmp - c  > max) {
            max = down[v] + tmp - c;
        }
    }
    down2[u] = max;
}

void dp(int u, int father = -1, int cf = 0)
{
    for (auto i : tree[u]) {
        auto v = i.to;
        auto c = i.cost;
        if (v == father) continue;
        auto tmp = back[u];
        if (back[v] - 2 * c > 0) tmp -= back[v] - 2 * c;
        if (f2[u] + tmp > f2[v]) {
            f2[v] = tmp - 2 * c;
        }
        if (father != -1) {
            tmp = back[father];
            if (back[u] - 2 * cf > 0) tmp -= back[u] - 2 * cf;
            if (back[father] - 2 * cf + down2[u] > f2[v])
                f2[v] = back[father] - 2 * cf + down2[u];
        }
        dp(v, u, c);
    }
}

void dp2(int u, int father = -1)
{
    for (auto i : tree[u]) {
        auto v = i.to;
        auto c = i.cost;
        if (v == father) continue;
        auto tmp = back[u];
        if (back[v] - 2 * c > 0) tmp -= back[v] - 2 * c;
        if (down[v] + tmp > f2[v]) {
            f2[v] = tmp - 2 * c;
        }
        dp2(v, u);
    }
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    int T; std::cin >> T;
    for (int ti = 1; ti <= T; ti++) {
        std::cout << "Case #" << ti << ":\n";
        std::cin >> n;
        init();
        for (int i = 1; i <= n; i++) std::cin >> value[i];
        for (int i = 1, x, y; i < n; i++) {
            ll c; std::cin >> x >> y >> c;
            add_edge(x, y, c);
        }

        dfs(1);
        dp(1);
        for (int i = 1; i <= n; i++)
            ans[i] = down[i];
        dp2(1);
        for (int i = 1; i <= n; i++)
            std::cout << ans[i] << "\n";
    }
}

